/*
 * Created on Jun 24, 2005
 */
package org.vectrics.event;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import org.apache.log4j.Logger;
import org.vectrics.SystemException;
import org.vectrics.config.ApplicationConfiguration;
import org.vectrics.domain.Domain;
import org.vectrics.hibernate.ThreadProperties;
import org.vectrics.mail.MailMessage;
import org.vectrics.mail.MailRecipientClass;
import org.vectrics.mail.MailRecipientManager;
import org.vectrics.mail.NotificationManager;
import org.vectrics.provider.CoreServiceLocator;
import org.vectrics.user.Person;
import org.vectrics.user.UserPrivilegeType;
import org.vectrics.user.PersonSearchCriteria;

/**
 * @author MMoore
 */
public abstract class EventHandler {
	private transient Logger log = Logger.getLogger(this.getClass());
	private Event event = null;
	
	public EventHandler() {
		super();
	}

	public final Event getEvent() {
		return(this.event);
	}
	
	abstract protected void doHandleEvent(Event event);
	//abstract protected Set findNotifyPersons();
	abstract protected EventEmailBuilder getEmailBuilder(Event event, Locale locale);
	//abstract protected void findNotifyUserPrivilegeTypes(Set userPrivilegeTypesToNotify);

	
	private void sendEmailToRecipientClass(Event event, MailRecipientClass recipClass) {
		EventEmailBuilder eventEmailBuilder = getEmailBuilder(event, recipClass.getLocale());
		if (eventEmailBuilder == null) {
			log.info("No email builder found for event type: " + this.getEvent().getEventType().getCode()
					+  "  Event handler class code: " + this.getEvent().getEventType().getHandlerClass());
		} else {
			Set notifyPersons = new HashSet();
			Iterator iter = recipClass.getPersons().iterator();
			while (iter.hasNext()) {
				Person person = (Person)iter.next();
				notifyPersons.add(person);
			}
			
			MailMessage mailMessage = null;
			
			//if ((recipClass.getHtml()) && (eventEmailBuilder.supportsHtml()))
			if (eventEmailBuilder.supportsHtml())
				mailMessage = eventEmailBuilder.getHtmlMailMessage();
			else
				mailMessage = eventEmailBuilder.getTextMailMessage();
			
			mailMessage.setFromName(CoreServiceLocator.getConfiguration().getSystemEmailFromName(this.event.getDomain()));
			mailMessage.setFromAddress(CoreServiceLocator.getConfiguration().getSystemEmailFromAddress(this.event.getDomain()));
			try {
				NotificationManager.getInstance().sendMessage(notifyPersons, mailMessage);
			} catch (Exception ex) {
				log.error("Exception sending email", ex);
			}
		}
	}

	
	public final void handleEvent(Event event) {
		this.event = event;
		if (event.getDomain() == null) {
			throw new SystemException("Event does not have a domain.");
		}
		
		if (log.isDebugEnabled())
			log.debug("Event being processed: " + event.getDescription());

		//ThreadProperties.forcedCommitAndNewSession();
		doHandleEvent(event);
		
		Set notifyPersons = findNotifyPersons();
		StringBuffer infoMessage = new StringBuffer();
		infoMessage.append("Event handler will notify the following people:");
		Iterator iter = notifyPersons.iterator();
		while (iter.hasNext()) {
			Person person = (Person)iter.next();
			if (person.getContactInfo() == null)
				infoMessage.append("\r\n * " + person.getName() + " - no email");
			else
				infoMessage.append("\r\n * " + person.getName() + " - " + person.getContactInfo().getEmail());
		}
		log.debug(infoMessage.toString());
		
		MailRecipientManager recipMgr = new MailRecipientManager();
		Set recipientClasses = recipMgr.findRecipientClasses(notifyPersons);
		iter = recipientClasses.iterator();
		while (iter.hasNext()) {
			MailRecipientClass recipClass = (MailRecipientClass)iter.next();
			sendEmailToRecipientClass(event, recipClass);
		}
			
	}
	
	
	abstract protected Set findNotifyPersons();

}
